package lesson3.com.demo.logging;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;


public class ClassThatLogs {
    private static final Logger LOG = Logger.getLogger(ClassThatLogs.class.getName());
    
    public void simpleMethodThatLogs(){
        LOG.log(Level.INFO, "in method  f()");
    }
    
    public void methodThatPrintsLoggerDetails(Logger logger) throws Exception{
        if(logger==null){
            logger = LOG;
        }
        Class cls = logger.getClass();
        Method[] meths = cls.getMethods();
        int mods;
        Object[] args = {};
        Object ret;
    
        for(Method meth: meths){
            mods = meth.getModifiers();
            if(Modifier.isStatic(mods)){
                continue;
            }
            if(!Modifier.isPublic(mods)){
                continue;
            }
            if(meth.getReturnType()==Void.TYPE){
                continue;
            }
            if(meth.getParameterTypes().length!=0){
                continue;
            }
            ret = meth.invoke(logger,args);
            System.out.println("The return of method LOG."+meth.getName()+" is "+ret);
        }
    }
    
    public void methodThatUsesACustomerHandler() throws Exception{
       MyLogger logger = new MyLogger();
       logger.addHandler(new MyHandler());
       logger.log(Level.INFO,"A log  message after adding a custom handler");
       methodThatPrintsLoggerDetails(logger);
    }

}

class ClassThatLogsTester {
    public static void main(String[] args) throws Exception{
        ClassThatLogs obj = new ClassThatLogs();
        //obj.simpleMethodThatLogs();
        //obj.methodThatPrintsLoggerDetails(null);
        obj.methodThatUsesACustomerHandler();
    }
}

class MyLogger extends Logger {
    
    MyLogger(){
        super("MyLogger",null);
        setLevel(Level.INFO);
    }
}

class MyHandler extends Handler{
    private File f = new File("myhandler.txt");
    private BufferedWriter getWriter(){
        try{
            FileWriter fw = new FileWriter(f,true); // true.. append to file
            BufferedWriter bw = new BufferedWriter(fw);
            return bw;
        }catch(Exception e){
            e.printStackTrace();
            System.exit(0);
        }
        return null;
    }
    
    private void write(String message){
        BufferedWriter bw=null;
        try{
            bw = getWriter();
            bw.write(new java.util.Date().toString()+": FROM MyHandler: "+ message);
            bw.newLine();
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(bw!=null){
                try{ bw.flush(); bw.close(); } catch(IOException ioe) {ioe.printStackTrace();}
            }
        }
    }

    @Override
    public void publish(LogRecord lr) {
        if(lr==null) return;
        write(lr.getMessage());
    }

    @Override
    public void flush() {
        // file writer flushes with each call to write()
    }

    @Override
    public void close() throws SecurityException {
        // file writer closes with each call to write()
    }
    
    public Level getLevel(){
        return Level.ALL;
    }
    
}
